/**
 * @file control_commands.h
 * @brief 控制命令处理头文件
 * @details 本文件声明了104协议中控制命令的处理功能，
 *          包括遥控命令的解析、构建、验证等操作。
 * 
 * @author zyb
 * @date 2025-10-16
 * @version 1.0
 * 
 * @note 控制命令格式严格按照IEC 60870-5-104协议规范
 * @warning 遥控命令包含选择和执行两个阶段
 * 
 * @see protocol_types.h
 * @see constants.h
 * @see error_codes.h
 */

#ifndef CONTROL_COMMANDS_H
#define CONTROL_COMMANDS_H

#ifdef __cplusplus
extern "C" {
#endif

#include "../../common/types/include/protocol_types.h"
#include "../../common/error/include/error_codes.h"

/* ==================== 遥控命令处理函数声明 ==================== */

/**
 * @brief 解析单点遥控命令
 * @details 从字节流中解析单点遥控命令，按照协议规范解析各个字段
 * 
 * @param buffer 输入缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param offset 偏移量
 * @param command 单点遥控命令结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 解析成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 * 
 * @note 单点遥控命令格式：1字节，包含SCS、QU、S/E位域
 * @warning 解析后的命令需要验证有效性
 * 
 * @see single_command_t
 * @see validate_single_command
 */
protocol_error_t parse_single_command(const uint8_t* buffer, size_t buffer_size, size_t offset, single_command_t* command);

/**
 * @brief 构建单点遥控命令
 * @details 将单点遥控命令结构转换为字节流，按照协议规范构建各个位域
 * 
 * @param command 单点遥控命令结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param offset 偏移量
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 构建成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 构建前建议先验证单点遥控命令结构的有效性
 * @warning 输出缓冲区必须有足够的空间
 * 
 * @see single_command_t
 * @see validate_single_command
 */
protocol_error_t build_single_command(const single_command_t* command, uint8_t* buffer, size_t offset);

/**
 * @brief 解析双点遥控命令
 * @details 从字节流中解析双点遥控命令，按照协议规范解析各个字段
 * 
 * @param buffer 输入缓冲区，不能为NULL
 * @param buffer_size 缓冲区大小
 * @param offset 偏移量
 * @param command 双点遥控命令结构输出，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 解析成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_BUFFER_TOO_SMALL: 缓冲区太小
 * 
 * @note 双点遥控命令格式：1字节，包含DCS、QU、S/E位域
 * @warning 解析后的命令需要验证有效性
 * 
 * @see double_command_t
 * @see validate_double_command
 */
protocol_error_t parse_double_command(const uint8_t* buffer, size_t buffer_size, size_t offset, double_command_t* command);

/**
 * @brief 构建双点遥控命令
 * @details 将双点遥控命令结构转换为字节流，按照协议规范构建各个位域
 * 
 * @param command 双点遥控命令结构，不能为NULL
 * @param buffer 输出缓冲区，不能为NULL
 * @param offset 偏移量
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 构建成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 * 
 * @note 构建前建议先验证双点遥控命令结构的有效性
 * @warning 输出缓冲区必须有足够的空间
 * 
 * @see double_command_t
 * @see validate_double_command
 */
protocol_error_t build_double_command(const double_command_t* command, uint8_t* buffer, size_t offset);

/* ==================== 遥控命令验证函数声明 ==================== */

/**
 * @brief 验证单点遥控命令
 * @details 验证单点遥控命令的各个位域是否有效
 * 
 * @param command 单点遥控命令结构，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 验证包括SCS值范围检查(0-1)、QU值范围检查(0-31)和S/E位域值范围检查
 * @warning 所有位域值都必须符合协议规范
 * 
 * @see single_command_t
 */
protocol_error_t validate_single_command(const single_command_t* command);

/**
 * @brief 验证双点遥控命令
 * @details 验证双点遥控命令的各个位域是否有效
 * 
 * @param command 双点遥控命令结构，不能为NULL
 * @return 协议错误码
 *         - PROTOCOL_SUCCESS: 验证成功
 *         - PROTOCOL_ERROR_NULL_POINTER: 空指针错误
 *         - PROTOCOL_ERROR_INVALID_PARAM: 无效参数
 * 
 * @note 验证包括DCS值范围检查(0-3)、QU值范围检查(0-31)和S/E位域值范围检查
 * @warning 所有位域值都必须符合协议规范
 * 
 * @see double_command_t
 */
protocol_error_t validate_double_command(const double_command_t* command);

/* ==================== 遥控命令状态处理函数声明 ==================== */

/**
 * @brief 获取单点遥控命令状态描述
 * @details 根据单点遥控命令的SCS值获取对应的状态描述
 * 
 * @param scs 单点命令状态值
 * @return 状态描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效的SCS值会返回"未知状态"
 * 
 * @see single_command_t
 */
const char* get_single_command_status_desc(uint8_t scs);

/**
 * @brief 获取双点遥控命令状态描述
 * @details 根据双点遥控命令的DCS值获取对应的状态描述
 * 
 * @param dcs 双点命令状态值
 * @return 状态描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效的DCS值会返回"未知状态"
 * 
 * @see double_command_t
 */
const char* get_double_command_status_desc(uint8_t dcs);

/**
 * @brief 获取遥控输出方式描述
 * @details 根据QU值获取对应的遥控输出方式描述
 * 
 * @param qu 限定词值
 * @return 输出方式描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效的QU值会返回"未知限定词"
 * 
 * @see single_command_t
 * @see double_command_t
 */
const char* get_qualifier_desc(uint8_t qu);

/**
 * @brief 获取选择/执行状态描述
 * @details 根据S/E位获取对应的选择/执行状态描述
 * 
 * @param se 选择/执行位值
 * @return 状态描述字符串
 * 
 * @note 返回的字符串是静态的，不需要释放
 * @warning 无效的S/E值会返回"未知状态"
 * 
 * @see single_command_t
 * @see double_command_t
 */
const char* get_select_execute_desc(uint8_t se);

/* ==================== 遥控命令流程处理函数声明 ==================== */

/**
 * @brief 检查遥控命令是否有效
 * @details 检查遥控命令的各个位域是否有效，包括状态值和限定词
 * 
 * @param command_type 命令类型 (1=单点, 2=双点)
 * @param status 命令状态值
 * @param qu 限定词值
 * @return 1表示有效，0表示无效
 * 
 * @note 验证包括状态值范围检查和限定词范围检查
 * @warning 无效的命令类型会导致返回0
 */
int is_valid_control_command(uint8_t command_type, uint8_t status, uint8_t qu);

/**
 * @brief 检查遥控命令是否为选择阶段
 * @details 检查遥控命令是否为选择阶段 (S/E=1)
 * 
 * @param se 选择/执行位值
 * @return 1表示是选择阶段，0表示是执行阶段
 * 
 * @note 选择阶段用于预选命令，执行阶段用于执行命令
 * @warning 无效的S/E值会导致返回0
 */
int is_select_phase(uint8_t se);

/**
 * @brief 检查遥控命令是否为执行阶段
 * @details 检查遥控命令是否为执行阶段 (S/E=0)
 * 
 * @param se 选择/执行位值
 * @return 1表示是执行阶段，0表示是选择阶段
 * 
 * @note 执行阶段用于执行已选择的命令
 * @warning 无效的S/E值会导致返回0
 */
int is_execute_phase(uint8_t se);

#ifdef __cplusplus
}
#endif

#endif /* CONTROL_COMMANDS_H */
